package com.smile.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import static com.smile.config.JacksonDateTimeConfig.FLEXIBLE_DATETIME_FORMATTER;

@Configuration
public class FeignConfig implements RequestInterceptor {

    @Bean
    public Retryer myRetryer() {
        return Retryer.NEVER_RETRY;
    }

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    // 使用表单编码器处理文件上传
    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder();
    }

    @Override
    public void apply(RequestTemplate template) {
        RequestAttributes requestAttributes1 = RequestContextHolder.getRequestAttributes();

        RequestContextHolder.setRequestAttributes(requestAttributes1, true);

//        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes1 == null)
            return;

        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes1).getRequest();

        // 只复制认证相关的头部，跳过内容类型和长度
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            System.out.println(headerName + ":" + headerValue);

            // 只复制认证头，其他由Feign处理
            if (isAuthorizationHeader(headerName)) {
                template.header(headerName, headerValue);
            }
        }

        // 处理认证令牌（示例）
        String token = extractToken(request);
        if (token != null) {
            template.header("Authorization", "Bearer " + token);
        }

        // 添加业务特定的头部
        template.header("cityNo", "0571");
        template.header("link-URL", "client");
    }

    // 辅助方法：识别认证头
    private boolean isAuthorizationHeader(String headerName) {
        return "authorization".equalsIgnoreCase(headerName) ||
                "x-auth-token".equalsIgnoreCase(headerName) ||
                "cookie".equalsIgnoreCase(headerName);
    }

    // 辅助方法：从请求中提取令牌
    private String extractToken(HttpServletRequest request) {
        // 实现实际的令牌提取逻辑
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        return null;
    }

    @Bean
    public Decoder feignDecoder() {
        return new SpringDecoder(feignHttpMessageConverter());
    }

    private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
        return () -> new HttpMessageConverters(
                // 创建自定义的MappingJackson2HttpMessageConverter
                createCustomMappingJackson2HttpMessageConverter()
        );
    }

    private MappingJackson2HttpMessageConverter createCustomMappingJackson2HttpMessageConverter() {
        // 创建自定义的ObjectMapper，配置如图片所示
        ObjectMapper customMapper = customObjectMapper();
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(customMapper);
        return converter;
    }


    // 复制图片中的customObjectMapper方法，并进行修改（使用完整的日期格式）
    private ObjectMapper customObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();

        // 支持灵活的日期时间格式反序列化
        // 这里假设FLEXIBLE_DATETIME_FORMATTER已经定义，比如：
        // private static final DateTimeFormatter FLEXIBLE_DATETIME_FORMATTER = ...;
        module.addDeserializer(LocalDateTime.class,
                new FlexibleLocalDateTimeDeserializer(FLEXIBLE_DATETIME_FORMATTER));

        // 修复序列化器：使用完整的日期格式
        module.addSerializer(LocalDateTime.class,
                new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        mapper.registerModule(module);
        // 可以注册其他模块，如JavaTimeModule，如果不需要自定义的序列化器/反序列化器，也可以直接使用JavaTimeModule并设置格式
        return mapper;
    }

    private MappingJackson2HttpMessageConverter createMappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        return converter;
    }
}